// -*- c++ -*-
/**************************************************************/
/*  This file is licensed from, and is a trade secret of:     */
/*                                                            */
/*    Mercury Computer Systems, Incorporated                  */
/*    199 Riverneck Road                                      */
/*    Chelmsford, Massachusetts 01824-2820                    */
/*    United States of America                                */
/*    Telephone + 1 978 256-1300                              */
/*                                                            */
/*  Refer to your Software License Agreement for provisions   */
/*  on use, duplication, or disclosure.                       */
/*  US. Government users and prime contractors are also       */
/*  governed by the following Data Rights Notice:             */
/*  Use, duplication or disclosure by the US. Government is   */
/*  subject to the provisions set forth in FAR 52.227-14 for  */
/*  restricted rights or other agency data rights provisions  */
/*  on commercial software and documentation, as applicable.  */
/*                                                            */
/*  This file: (a) was developed at private expense, and no   */
/*  part was developed with government funds, (b) is a        */
/*  trade secret of Mercury Computer Systems, Inc. for the    */
/*  purposes of the Freedom of Information Act, (c) is        */
/*  "commercial computer software" subject to limited         */
/*  utilization as provided in the above noted Software       */
/*  License Agreement and (d) is in all respects data         */
/*  belonging exclusively to Mercury Computer Systems, Inc..  */
/*                                                            */
/**************************************************************/

/******************************************************************/
/* Copyright (c) 1999-2003, Mercury Computer Systems, Inc.,       */
/* Chelmsford MA.,and all third party embedded software sources.  */
/* All rights reserved under the Copyright laws of US. and        */
/* international treaties.                                        */
/*                                                                */
/* Patent Pending                                                 */
/******************************************************************/


//$COPYRIGHT_END


#ifndef MSK_H__
#define MSK_H__

#include <iostream>
#include <string>
#include <math.h>

#include "CF__Resource_impl.h"
#include "AudioPort_impl.h"
#include "SceOsThreadManager.h"
#include "mc_error.h"

#ifndef PI
#define PI 3.14159265358979
#endif

#ifdef _WIN32
#pragma warning( disable : 4275 )
#pragma warning( disable : 4251 )
#endif

#ifdef _WIN32
#ifdef MSK_EXPORTS
#define MOD_EXPORT __declspec(dllexport)
#else
#define MOD_EXPORT __declspec(dllimport)
#endif
#else
#define MOD_EXPORT 
#endif

class MOD_EXPORT MskModulator : public CF__Resource_impl {
public: 
  static status
  Create (MskModulator *& ModulatorHandle,
	  const char * identifier);

  // From CF::Resource
  void start ()
    throw (CORBA::SystemException, CF::Resource::StartError);
  void stop ()
    throw (CORBA::SystemException, CF::Resource::StopError);

  // From CF::PortSupplier
  CORBA::Object_ptr getPort (const CORBA::Char * name)
    throw (CORBA::SystemException, CF::PortSupplier::UnknownPort);

private:
  MskModulator (const char *identifier);
  ~MskModulator ();

  // Separate thread master function
  static void RunWorker (void * param);

  // Inner loop function that deals with external commands
  void RunLoop ();
  // Inner loop method that performs component business logic
  virtual status Run ();

  status Init ();
  status Modulate (char * bits,
		   int NumBits,
		   CMPLX_INT16 * mod_syms,
		   int & NumSamples,
		   char & last_Q_bit);

  short *m_pulse_shape;
  unsigned m_uiLenPulseShape;
  unsigned m_uiSamplesPerSymbol;

  unsigned int m_input_buffer_size;
  unsigned int m_output_buffer_size;
  unsigned int m_max_val; // maximum value output by MSK modulator pulse

  char * m_input;   // input data buffer
  int m_input_count;  // number of samples currently in the buffer
  int m_samples_read; // number of samples read from the buffer

  CMPLX_INT16 * m_output;

  Fm3trInPort_impl * m_fm3trin;
  MskOutPort_impl * m_complexout;

  SCE::OS::ThreadManager m_thread;
  bool m_threadrunning;
  bool m_bStop;
};


class MOD_EXPORT MskDemodulator : public CF__Resource_impl {
public:

  /*
   * FrameSize governs the maximum number of samples that are
   * taken from the modulator at a time.  If this number is too
   * small (smaller than the number of samples representing a
   * single FM3TR frame) the waveform will be hindered by
   * CORBA overhead.  This number is relative to the number of
   * samples per symbol. A good value is 1,024.
   */

  enum {
    FrameSize = 1024
  };

  static status
  Create (MskDemodulator *& DemodHandle,
	  const char * identifier);

  // From CF::Resource
  void start ()
    throw (CORBA::SystemException, CF::Resource::StartError);
  void stop ()
    throw (CORBA::SystemException, CF::Resource::StopError);

  // From CF::PortSupplier
  CORBA::Object_ptr getPort (const CORBA::Char * name)
    throw (CORBA::SystemException, CF::PortSupplier::UnknownPort);

private:
  MskDemodulator (const char *identifier);
  ~MskDemodulator ();

  // Separate thread master function	
  static void RunWorker (void * param);

  // Inner loop function that deals with external commands
  void RunLoop ();
  // Inner loop method that performs component business logic
  virtual status Run ();


  status Init ();
  void Demodulate (CMPLX_INT16 * data,
		   unsigned & len_data,
		   char * demod_syms,
		   unsigned & num_syms,
		   int scale);

  unsigned SymbolSynch (CMPLX_INT16 * data,
			unsigned len_data,
			int scale);


  unsigned m_uiLenPulseShape;
  short * m_j_pulse_shape;
  float m_pulseEnergy;

  unsigned m_uiSamplesPerSymbol;
  unsigned m_uiSymbolRate;
  unsigned m_uiMaxVal;

  unsigned int m_input_buffer_size;
  CMPLX_INT16 * m_input;    // input data buffer
  int m_input_count;        // number of samples in buffer
  int m_samples_read;       // number of samples read from buffer

  CMPLX_INT16 * m_mod_syms;
  char * m_demod_syms;

  MskInPort_impl * m_complexin;
  Fm3trOutPort_impl * m_fm3trout;

  SCE::OS::ThreadManager m_thread;
  bool m_threadrunning;
  bool m_bStop;
};

#endif /* MSK_H */
